package cc.co.cutenimy.nimyexplore.model.jdbc;

import java.util.HashMap;
import java.util.Map;
import java.util.Properties;

import cc.co.cutenimy.nimyexplore.model.connection.ConnectionOptions;
import cc.co.cutenimy.nimyexplore.model.connection.Option;
import cc.co.cutenimy.nimyexplore.model.expression.ExpressionMachine;
import cc.co.cutenimy.nimyexplore.model.expression.RegularExpressionMachine;

/**
 * A instance of a given ConnectionOptions.
 * 
 * This instance can used to be create a actual JDBC {@link java.sql.Connection}
 * 
 * @author 234aini@gmail.com
 * 
 */
public class ConnectionInstance {

	public ConnectionInstance(final ConnectionOptions options) {
		this.options = options;
		this.expressionMachine = new RegularExpressionMachine(this);
	}

	private String alias;

	private final ExpressionMachine expressionMachine;
	private final ConnectionOptions options;
	private final Map<Option, OptionValue> valueMap = new HashMap<Option, OptionValue>(
			8);

	public String getUrl() {
		return expressionMachine.eval(options.getUrlExpression());
	}

	public Option getOptionByName(String string) {
		for (Option option : options.getOption()) {
			if (option.getName().equals(string)) {
				return option;
			}
		}
		return null;
	}

	public void setOptionByName(final String optionName, final String value) {
		boolean setted = false;
		for (Option option : valueMap.keySet()) {
			if (option.getName().equals(optionName)) {
				valueMap.put(option, new OptionValue(value));
				setted = true;
			}
		}
		if (!setted) {
			throwIllegalOptionNameException(optionName);
		}
	}

	private void throwIllegalOptionNameException(final String optionName) {
		throw new IllegalArgumentException(
				"The option does not exist in the option declare file. - '"
						+ optionName + "'");
	}

	public OptionValue getOptionValueByName(final String optionName) {
		Option option = getOptionByName(optionName);
		if (option == null) {
			throwIllegalOptionNameException(optionName);
		}
		return valueMap.get(option);
	}

	public void setOptionValueByName(final String optionName,
			final OptionValue stringValue) {
		Option optionByName = getOptionByName(optionName);
		if (optionByName == null) {
			throwIllegalOptionNameException(optionName);
		}
		valueMap.put(optionByName, stringValue);
	}

	public ExpressionMachine getExpressionMachine() {
		return expressionMachine;
	}

	public Properties getProperties() {
		Properties properties = new Properties();
		for (Option option : valueMap.keySet()) {
			if (option != null) {
				OptionValue optionValue = valueMap.get(option);
				if (optionValue != null) {
					properties.put(option.getName(),
							optionValue.getStringValue());
				}
			}
		}
		return properties;
	}

	public String getAlias() {
		return alias;
	}

	public void setAlias(String alias) {
		this.alias = alias;
	}
}
